import { AST, Token } from "../ch8";

class ExprNode extends AST{
    static tINVALID = 0;
    static tINTEGER = 1;
    static tVECTOR = 2; //List

    evalType:number = 0;

    constructor(payload:Token | null){
        super(payload)
    }
    
    toString(){
        if(this.evalType != ExprNode.tINVALID){
            return super.toString() 
            + `<type=${this.evalType == ExprNode.tINTEGER ? "tINTEGER" : "tVECTOR"}>` 
        }
        return super.toString()
    }
}

class IntNode extends ExprNode {
    constructor(t:Token){
        super(t);
        this.evalType = ExprNode.tINTEGER;
    }
}

class VectorNode extends ExprNode {
    constructor(t:Token | null,elements:ExprNode[]){
        super(t);
        this.evalType = ExprNode.tVECTOR;
        //
        this.children = this.children.concat(elements);
    }
}

class AddNode extends ExprNode {
    constructor(
        left:ExprNode,
        addToken:Token,
        right:ExprNode
    ){
        super(addToken);
        this.addChild(left);
        this.addChild(right)
    }

    getEvalType(){
        let left = this.children[0] as ExprNode;
        let right = this.children[1] as ExprNode;

        if(left.evalType == ExprNode.tINTEGER
        && right.evalType == ExprNode.tINTEGER){
            return ExprNode.tINTEGER;
        }

        if(left.evalType == ExprNode.tVECTOR
        && right.evalType == ExprNode.tVECTOR){
            return ExprNode.tVECTOR
        }

        return ExprNode.tINVALID
    }
}



export {
    ExprNode,
    IntNode,
    AddNode,
    VectorNode
}